Spring Bootでデータベースに接続
はじめに
前回はSpring Bootの導入を行い、簡単に実行してみました。 今回はもっと進めて、ローカルのデータベースに接続してみます。
環境
OS : Mac OSX 10.10.5 DB : Postgres 9.5.1
プロジェクト作成
JPAとPostgreSQLにチェックを入れます。 JPAはSQLを書かずにCRUDができるので便利です。
準備
データベース、テーブルの用意
まず、PostgreSQLでデータベースとテーブルを作成しておきます。
CREATE DATABASE sbdb; CREATE TABLE counter1 ( id SERIAL PRIMARY KEY , title VARCHAR(16) , count INT); INSERT INTO counter1 VALUES (0,'all',0) , (1,'select',0) , (2,'update',0) , (3,'delete',0);
sbdb=# select * from counter1 ; id | title | count ----+--------+------- 0 | all | 0 1 | select | 0 2 | update | 0 3 | delete | 0 (4 rows)
設定ファイル
build.gradle
buildscript { ext { springBootVersion = '1.3.5.RELEASE' } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") } } apply plugin: 'java' apply plugin: 'eclipse' apply plugin: 'spring-boot' jar { baseName = 'demo' version = '0.0.1-SNAPSHOT' } sourceCompatibility = 1.8 targetCompatibility = 1.8 repositories { mavenCentral() } dependencies { compile('org.springframework.boot:spring-boot-starter-web') compile('org.springframework.boot:spring-boot-starter-data-jpa') runtime('org.postgresql:postgresql') testCompile('org.springframework.boot:spring-boot-starter-test') } eclipse { classpath { containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' } }
依存関係にJPAとPostgreSQLが追加されています。
application.xml
spring: datasource: url: jdbc:postgresql://localhost/sbdb username: XXXX password: XXXX driverClassName: org.postgresql.Driver
src/main/resourcesの下に、Folder「config」を作成してFile「application.yml」を作成します。 ここにデータベースの接続情報を書き込みます。
コード
DBApplication
ここから始まります。
package com.pstgrs.jpa; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class DBApplication { public static void main(String[] args) { SpringApplication.run(DBApplication.class, args); } }
6行目、@SpringBootApplicationで、SpringBoot設定の自動化します。楽です。 10行目で起動です。
Counter
Entityクラスです。 データベースのカラムを設定します。
package com.pstgrs.jpa; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="counter1") public class Counter { @Id @GeneratedValue(strategy=GenerationType.IDENTITY) private int id; @Column(name="title") private String title; @Column(name="count") private int count; // getter, setter public Integer getID() {return id;} public void setId(Integer no) {this.id = no;} public String getTitle() {return title;} public void setTitle(String title) {this.title = title;} public int getCount() {return count;} public void setCount(int count) {this.count = count;} }
10行目、@EntityでJPAに管理してもらいます。 11行目、@Tableで接続するテーブルを指定。 14行目、@Idで変数idをプライマリーキーに指定。 15行目、@GeneratedValueで値を指定しなくても自動生成する様に設定。 18〜22行目、その他カラムの設定。
getterとsetterはlombokでも良いですね。
CounterRepository
package com.pstgrs.jpa; import org.springframework.data.jpa.repository.JpaRepository; public interface CounterRepository extends JpaRepository<Counter, Integer> { }
このリポジトリでJPAを継承すれば、SQLを書かずに済みます。
CounterService
package com.pstgrs.jpa; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @Service @Transactional public class CounterService { @Autowired CounterRepository repository; public List<Counter> selectAll() { return repository.findAll(new Sort(Sort.Direction.ASC, "id")); } }
10行目、サービスに設定。 11行目、トランザクション設定。 14〜15行目、@Autowiredでリポジトリを繋げ、後述のCounterクラスで使用する実行内容を作っていきます。
18行目、repository.findAll()で、 SELECT * FROM counter1; と同じ意味になりますが、Sort.Direction.ASCで、"id"を昇順と指定しているので、 SELECT * FROM counter1 ORDER BY id; と同じ意味になります。
Controller
package com.pstgrs.jpa; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; @RestController @RequestMapping("/counter") public class Controller { @Autowired CounterService service; // 一覧表示 @RequestMapping(value="/selectall", method=RequestMethod.GET) public List<Counter> counterSelectAll() { return service.selectAll(); } }
14行目、@RequestMapping("/counter")とすると、http://localhost:8080/counter で繋がります。
17〜18行目、サービスに繋げます。
21行目、counterSelectAll()の@RequestMappingでは、 value="/selectall", method=RequestMethod.GETと設定しているので、 http://localhost:8080/counter/selectall で繋がります。
コマンドラインから実行
作ったアプリを起動してからコマンド実行で確認します。
$ curl http://localhost:8080/counter/selectall
[{"id":0,"title":"all","count":0},{"id":1,"title":"select","count":0},{"id":2,"title":"update","count":0},{"id":3,"title":"delete","count":0}]ip-172-18-0-147:~ cm$
JSONで帰って来ました。
さいごに
アノテーションが多いので最初は戸惑いますが、段々と見慣れてくると思います。 サービスについては、リポジトリからコントローラーに直接接続できるようですが、使用した方がより本格的の様です。